package cn.zly.spring.context.support;

import cn.zly.spring.beans.factory.config.BeanFactoryPostProcessor;
import cn.zly.spring.beans.factory.config.BeanPostProcessor;
import cn.zly.spring.beans.factory.ConfigurableListableBeanFactory;
import cn.zly.spring.context.ConfigurableApplicationContext;
import cn.zly.spring.core.io.DefaultResourceLoader;

import java.util.Map;


/**
 * @author zhanglianyong
 * @date 2025/1/21
 */
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {


	@Override
	public void refresh() throws Exception {
		// 1. 创建BeanFactory，并加载BeanDefinition
		refreshBeanFactory();

		// 2. 获取BeanFactory
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();

		// 3.执行BeanFactory后置处理
		invokeBeanFactoryPostProcessors(beanFactory);

		// 4.注册BeanPostProcessor
		registerBeanPostProcessors(beanFactory);

		// 5.实例化单例对象
		beanFactory.preInstantiateSingletons();
	}

	private void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		Map<String, BeanFactoryPostProcessor> beanFactoryPostProcessorMap = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class);

		for (BeanFactoryPostProcessor beanFactoryPostProcessor : beanFactoryPostProcessorMap.values()) {
			beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
		}
	}

	protected abstract ConfigurableListableBeanFactory getBeanFactory();

	protected abstract void refreshBeanFactory() throws Exception;


	public void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		Map<String, BeanPostProcessor> beanPostProcessorMap = beanFactory.getBeansOfType(BeanPostProcessor.class);
		for (BeanPostProcessor beanPostProcessor : beanPostProcessorMap.values()) {
			beanFactory.addBeanPostProcessor(beanPostProcessor);
		}
	}
}
